﻿using System;
using cszmcaux;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LKLCode.MotionControlCard.Zmotion
{
    internal class ZmcAxis : Test_IAxis
    {
        private int axisIndex;  //轴编号
        public int Index { get { return axisIndex; } }
        private IntPtr zmhandle;//句柄
        public ZmcAxis(IntPtr zmcHandle, AxisInitType axisInitType)
        {
            this.zmhandle = zmcHandle;
            this.axisIndex = axisInitType.AxisIndex;
            this.Type = axisInitType.AxisType;
        }

        /// <summary>
        /// 轴类型
        /// </summary>
        public AxisType Type
        {
            //Atype类型 描述
            //0     虚拟轴
            //1     脉冲方向方式的步进或伺服
            //2     模拟信号控制方式的伺服
            //3     正交编码器
            //4     脉冲方向输出+正交编码器输入
            //5     脉冲方向输出+脉冲方向编码器输入
            //6     脉冲方向方式的编码器
            //7     脉冲方向方式步进或伺服+EZ信号输入
            //8     ZCAN扩展脉冲方向方式步进或伺服
            //9     ZCAN扩展正交编码器
            //10    ZCAN扩展脉冲方向方式的编码器
            //21    振镜轴类型，需要控制器支持
            //      缺省系统周期250us，振镜刷新周期50us，与固件有关
            //      可以使用普通轴的所有运动控制指令，支持振镜轴与其它轴类型混合插补
            //50    RTEX周期位置模式，需RTEX控制器
            //51    RTEX周期速度模式，需RTEX控制器
            //52    RTEX周期力矩模式，需RTEX控制器
            //      请先关闭驱动器2自由度控制模式，并设置设置速度限制
            //65    EtherCAT周期位置模式，需支持EtherCAT
            //66    EtherCAT周期速度模式，需支持EtherCAT
            //      DRIVE_PROFILE要设置为20或以上
            //67    EtherCAT周期力矩模式，需支持EtherCAT
            //      DRIVE_PROFILE要设置为30或以上
            //70    EtherCAT自定义操作，只读取编码器，需支持EtherCAT

            get
            {
                int val = 0;
                AxisType axisType;
                zmcaux.ZAux_Direct_GetAtype(zmhandle, axisIndex, ref val);
                switch (val)
                {
                    case 1:
                        axisType = AxisType.StepperMotor;
                        break;
                    case 65:
                        axisType = AxisType.EtherCatPosMotor;
                        break;
                    case 66:
                        axisType = AxisType.EtherCatSpeedMotor;
                        break;
                    case 67:
                        axisType = AxisType.EtherCatTorsionMotor;
                        break;
                    default:
                        throw new ArgumentException("UnKnow axisIndex type of:" + val);
                }
                return axisType;
            }
            set
            {

                int val;
                switch (value)
                {
                    case AxisType.StepperMotor:
                        val = 1;
                        break;
                    case AxisType.EtherCatPosMotor:
                        MaxTorque = 1000;
                        val = 65;
                        break;
                    case AxisType.EtherCatSpeedMotor:
                        MaxTorque = 1000;
                        val = 66;
                        break;
                    case AxisType.EtherCatTorsionMotor:
                        MaxTorque = 1000;
                        val = 67;
                        break;
                    default:
                        throw new ArgumentException("UnKnow axisIndex type of:" + value);
                }

            }
        }

        /// <summary>
        /// 轴反向
        /// </summary>
        public bool Invert
        {
            get
            {
                if (Type == AxisType.StepperMotor)
                {
                    int mode = 0;
                    zmcaux.ZAux_Direct_GetInvertStep(zmhandle, axisIndex, ref mode);
                    return mode == 0 ? false : true;
                }
                else
                {
                    //这边可填入总线型驱动器品牌
                    int mode = 0;
                    return mode == 0 ? false : true;
                }
            }
            set
            {
                if (Type == AxisType.StepperMotor)
                {
                    if (value == true)
                    {
                        zmcaux.ZAux_Direct_SetInvertStep(zmhandle, axisIndex, 2);
                    }
                    else
                    {
                        zmcaux.ZAux_Direct_SetInvertStep(zmhandle, axisIndex, 0);
                    }
                }
                else
                {
                    //这边可填入总线型驱动器品牌
                }
            }
        }

        /// <summary>
        /// 轴速度
        /// </summary>
        public float Speed
        {
            get
            {
                float _speed = 0;
                zmcaux.ZAux_Direct_GetSpeed(zmhandle, axisIndex, ref _speed);
                return _speed;
            }
            set
            {
                zmcaux.ZAux_Direct_SetSpeed(zmhandle, axisIndex, value);
            }
        }

        /// <summary>
        /// 轴加速度
        /// </summary>
        public float Accel
        {
            get
            {
                float _accel = 0;
                zmcaux.ZAux_Direct_GetAccel(zmhandle, axisIndex, ref _accel);
                return _accel;
            }
            set
            {
                zmcaux.ZAux_Direct_SetAccel(zmhandle, axisIndex, value);
            }
        }

        /// <summary>
        /// 轴减速度
        /// </summary>
        public float Decel
        {
            get
            {
                float _decle = 0;
                zmcaux.ZAux_Direct_GetDecel(zmhandle, axisIndex, ref _decle);
                return _decle;
            }
            set
            {
                zmcaux.ZAux_Direct_SetDecel(zmhandle, axisIndex, value);
            }
        }

        /// <summary>
        /// 脉冲当量
        /// </summary>
        public float Unit
        {
            get
            {
                float _unit = 0;
                zmcaux.ZAux_Direct_GetUnits(zmhandle, axisIndex, ref _unit);
                return _unit;
            }
            set
            {
                zmcaux.ZAux_Direct_SetUnits(zmhandle, axisIndex, value);
            }
        }



        /// <summary>
        /// 相对运动
        /// </summary>
        public void Move(float distance)
        {
            zmcaux.ZAux_Direct_Single_Move(zmhandle, axisIndex, distance);
        }

        /// <summary>
        /// Jog运动
        /// </summary>
        /// <param name="dir"></param>
        public void MoveJog(bool dir)
        {
            int val = dir == true ? 1 : -1;
            zmcaux.ZAux_Direct_Single_Vmove(zmhandle, axisIndex, val);
        }






        /// <summary>
        /// 最大扭力值 单位：电机额定输出扭矩的千分之一
        /// </summary>
        public int MaxTorque
        {
            get
            {
                int val = 0;
                zmcaux.ZAux_BusCmd_GetMaxDriveTorque(zmhandle, (uint)axisIndex, ref val);
                return val;
            }
            set
            {
                zmcaux.ZAux_BusCmd_SetMaxDriveTorque(zmhandle, (uint)axisIndex, value);
            }
        }

        /// <summary>
        /// 轴状态
        /// </summary>
        public AxisStatus Status { get { return status; } }
        private AxisStatus status;

        public void EmergentStop()
        {
            status.IsEmergentStop = true;
        }

        public void Pause()
        {
            if (status.IsEmergentStop == true) return;
            status.IsPause = true;
        }

        /// <summary>
        /// 轴从暂停中恢复
        /// </summary>
        public void Resume()
        {
           if( status.IsEmergentStop == true) return;
            status.IsPause = true;

        }

        /// <summary>
        /// 解除轴急停
        /// </summary>
        public void ResetEmergentStop()
        {
            status.IsEmergentStop = false;
            status.IsPause = false;
        }














    }
}
